﻿#pragma once
#include "AsContainerBasics.h"

AS_MEMBER_CLASS_DECLARATION(AsBinaryFile);

class AS_BASIC_EXPORT AsBinaryFile {
public:
	enum Flag {
		Write,
		Read,
		ReadWrite,
		WriteTruncate,
	};

public:
	AsBinaryFile();
	AsBinaryFile(std::string filename, unsigned int flag);
	virtual ~AsBinaryFile();

private:
	AS_MEMBER_CLASS(AsBinaryFile)* mp;

public:
	bool isOpen() const;

public:
	bool open(std::string filename, unsigned int flag);
	void close();
	void seekp(size_t pos);
	void seekg(size_t pos);
	void seekp(size_t pos, int mode);
	void seekg(size_t pos, int mode);
	size_t tellp();
	size_t tellg();
	void write(const char* ptr, size_t size);
	void read(char* ptr, size_t size);

public:
	template <typename _Type>
	AsBinaryFile& operator<<(const _Type& data) {
		write((const char*)&data, sizeof(data));
		return *this;
	}
	template <typename _Type>
	AsBinaryFile& operator>>(_Type& data) {
		read((char*)&data, sizeof(data));
		return *this;
	}
	AsBinaryFile& operator<<(const std::string& data);
	AsBinaryFile& operator>>(std::string& data);
	template <typename _TypeFirst, typename _TypeSecond>
	AsBinaryFile& operator<<(const std::pair<_TypeFirst, _TypeSecond>& datapair) {
		*this << datapair.first;
		*this << datapair.second;
		return *this;
	}
	template <typename _TypeFirst, typename _TypeSecond>
	AsBinaryFile& operator>>(std::pair<_TypeFirst, _TypeSecond>& datapair) {
		*this >> datapair.first;
		*this >> datapair.second;
		return *this;
	}
	template <typename _Type>
	AsBinaryFile& operator<<(const std::vector<_Type>& datas) {
		*this << datas.size();
		for (const auto& data : datas) *this << data;
		return *this;
	}
	template <typename _Type>
	AsBinaryFile& operator>>(std::vector<_Type>& datas) {
		size_t size = 0;
		*this >> size;
		datas.resize(size);
		for (auto& data : datas) *this >> data;
		return *this;
	}
	AsBinaryFile& operator<<(const cv::Mat& mat);
	AsBinaryFile& operator>>(cv::Mat& mat);

};



